package cn.zhonghuanzhiyuan.sprc.basicinfo.controller;

import cn.org.bachelor.web.json.JsonResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * @BelongsProject: eprs
 * @BelongsPackage: cn.zhonghuanzhiyuan.eprs.command.controller
 * @Author: Hyw
 * @CreateTime: 2024-01-11  18:03
 * @Description: TODO
 * @Version: 1.0
 */
@Api(tags = "xxx-xxx")
@RestController
@RequestMapping("/file")
@CrossOrigin // 线上不需要 （要注掉）
public class FileCommonController {

    @Value("${uploadPath.linux:''}")
    private String linuxPath;
    @Value("${uploadPath.windows:''}")
    private String windowsPath;
    @Value("${uploadPath.relative:''}")
    private String relative;

    @ApiOperation("上传文件(单个)")
    @PostMapping(value = "/uploadFile", headers = "content-type=multipart/form-data")
    public ResponseEntity<JsonResponse> uploadFile(@RequestParam MultipartFile file) {
        Assert.isTrue(!file.isEmpty(), "上传文件失败，文件名为空");
        if (!file.isEmpty()) {
            String originalFilename = file.getOriginalFilename();
            Assert.isTrue(!StringUtils.isEmpty(originalFilename), "上传文件失败，文件名为空");
            // 文件重命名
            String newFileName = System.currentTimeMillis() + "_" + originalFilename;
            // 文件保存的目录
            String saveDirPath = "";
            // 判断系统
            //增加判断 dataType 不同的值上传到不同的目录
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("win")) {
                saveDirPath = windowsPath;
            } else {
                saveDirPath = linuxPath;
            }
            String dataForm = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            saveDirPath = saveDirPath + dataForm + "/";
            // 判断文件夹是否存在
            File upload = new File(saveDirPath);
            if (!upload.exists()) {
                upload.mkdirs();
            }
            String filePath = saveDirPath + newFileName;
            System.out.println(filePath);
            try (BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(filePath))) {
                out.write(file.getBytes());
                out.flush();
                newFileName = dataForm + "/" + newFileName;
                // 文件web浏览路径
                return JsonResponse.createHttpEntity(relative + newFileName);
            } catch (FileNotFoundException e) {
                return JsonResponse.createHttpEntity(false, "上传文件失败 FileNotFoundException：" + e.getMessage());
            } catch (IOException e) {
                return JsonResponse.createHttpEntity(false, "上传文件失败 IOException：" + e.getMessage());
            }
        } else {
            return JsonResponse.createHttpEntity(false, "上传文件失败，文件为空");
        }
    }

    @ApiOperation("上传文件(批量)")
    @PostMapping(value = "/uploadFileList", headers = "content-type=multipart/form-data")
    public ResponseEntity<JsonResponse> uploadFileList(@RequestParam("files") MultipartFile[] files) {
        ArrayList list = new ArrayList();
        for (MultipartFile file : files) {
            Assert.isTrue(!file.isEmpty(), "上传文件失败，文件名为空");
            if (!file.isEmpty()) {
                String originalFilename = file.getOriginalFilename();
                Assert.isTrue(!StringUtils.isEmpty(originalFilename), "上传文件失败，文件名为空");
                // 文件重命名
                String newFileName = System.currentTimeMillis() + "_" + originalFilename;
                // 文件保存的目录
                String saveDirPath = "";
                // 判断系统
                //增加判断 dataType 不同的值上传到不同的目录
                String os = System.getProperty("os.name");
                if (os.toLowerCase().startsWith("win")) {
                    saveDirPath = windowsPath;
                } else {
                    saveDirPath = linuxPath;
                }
                String dataForm = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                saveDirPath = saveDirPath + dataForm + "/";
                // 判断文件夹是否存在
                File upload = new File(saveDirPath);
                if (!upload.exists()) {
                    upload.mkdirs();
                }
                String filePath = saveDirPath + newFileName;
                try (BufferedOutputStream out = new BufferedOutputStream(
                        new FileOutputStream(filePath))) {
                    out.write(file.getBytes());
                    out.flush();
                    newFileName = dataForm + "/" + newFileName;
                    //返回文件路径
                    list.add(relative + newFileName);
                } catch (FileNotFoundException e) {
                    return JsonResponse.createHttpEntity(false, "上传文件失败 FileNotFoundException：" + e.getMessage());
                } catch (IOException e) {
                    return JsonResponse.createHttpEntity(false, "上传文件失败 IOException：" + e.getMessage());
                }
            } else {
                return JsonResponse.createHttpEntity(false, "上传文件失败，文件为空");
            }
        }
        // 文件web浏览路径
        return JsonResponse.createHttpEntity(list.toArray());
    }

    @ApiOperation(value = "下载文件")
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletRequest request, HttpServletResponse response, @RequestParam String url) throws IOException {
        File file = new File(url);
        response.setCharacterEncoding(request.getCharacterEncoding());
        String fileName = file.getName();
        InputStream in = new FileInputStream(url);// 根据文件路径 封装成文件输入流。 把磁盘文件，转换为输入流，存入到内存中
        int len = 0;
        byte[] buffer = new byte[1024];// 声明了一个1KB的字节 的缓冲区
        // 设置响应头 content-disposition： 就是设置文件下载的打开方式，默认会在网页上打开，
        // 设置attachment;filename= 就是为了以下载方式来打开文件
        // "UTF-8"设置如果文件名有中文就不会乱码
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream out = response.getOutputStream(); // 获取输出流
        // 循环读取文件，每次读1KB，避免内存溢出
        while ((len = in.read(buffer)) > 0) { // 从缓冲区读取内容
            out.write(buffer, 0, len);// // 往客户端写入 将缓冲区的数据输出到客户端浏览器
        }
        in.close();
    }
}
